#ifndef ICM20948_H_
#define ICM20948_H_


#include "stdint.h"
#include <math.h>
/* define ICM-20948 Device I2C address*/
#define I2C_ADD_ICM20948            0x68
#define I2C_ADD_ICM20948_AK09916    0x0C
#define I2C_ADD_ICM20948_AK09916_READ  0x80
#define I2C_ADD_ICM20948_AK09916_WRITE 0x00

/* define ICM-20948 Register */
/* user bank 0 register */
#define REG_ADD_WIA             0x00
#define REG_VAL_WIA             0xEA
#define REG_ADD_USER_CTRL       0x03
#define REG_VAL_BIT_DMP_EN          0x80
#define REG_VAL_BIT_FIFO_EN         0x40
#define REG_VAL_BIT_I2C_MST_EN      0x20
#define REG_VAL_BIT_I2C_IF_DIS      0x10
#define REG_VAL_BIT_DMP_RST         0x08
#define REG_VAL_BIT_DIAMOND_DMP_RST 0x04
#define REG_ADD_PWR_MIGMT_1     0x06
#define REG_VAL_ALL_RGE_RESET   0x80
#define REG_VAL_RUN_MODE        0x01    //Non low-power mode
#define REG_ADD_LP_CONFIG       0x05
#define REG_ADD_PWR_MGMT_1      0x06
#define REG_ADD_PWR_MGMT_2      0x07
#define REG_VAL_SENSORS_ON      0x00
#define REG_VAL_DISABLE_GYRO    0x07
#define REG_VAL_DISABLE_ACC     0x38
#define REG_ADD_ACCEL_XOUT_H    0x2D
#define REG_ADD_ACCEL_XOUT_L    0x2E
#define REG_ADD_ACCEL_YOUT_H    0x2F
#define REG_ADD_ACCEL_YOUT_L    0x30
#define REG_ADD_ACCEL_ZOUT_H    0x31
#define REG_ADD_ACCEL_ZOUT_L    0x32
#define REG_ADD_GYRO_XOUT_H     0x33
#define REG_ADD_GYRO_XOUT_L     0x34
#define REG_ADD_GYRO_YOUT_H     0x35
#define REG_ADD_GYRO_YOUT_L     0x36
#define REG_ADD_GYRO_ZOUT_H     0x37
#define REG_ADD_GYRO_ZOUT_L     0x38
#define REG_ADD_TEMP_OUT_H      0x39
#define REG_ADD_TEMP_OUT_L      0x3A
#define REG_ADD_EXT_SENS_DATA_00 0x3B
#define REG_ADD_FIFO_EN_1		0x66
#define REG_ADD_FIFO_EN_2		0x67
#define REG_ADD_FIFO_RST		0x68
#define REG_ADD_FIFO_MODE		0x69
#define REG_ADD_FIFO_COUNTH		0x70
#define REG_ADD_FIFO_COUNTL		0x71
#define REG_ADD_FIFO_R_W		0x72
#define REG_ADD_REG_BANK_SEL    0x7F
#define REG_VAL_REG_BANK_0  0x00
#define REG_VAL_REG_BANK_1  0x10
#define REG_VAL_REG_BANK_2  0x20
#define REG_VAL_REG_BANK_3  0x30

/* user bank 1 register */
/* user bank 2 register */
#define REG_ADD_GYRO_SMPLRT_DIV 0x00
#define REG_ADD_GYRO_CONFIG_1   0x01
#define REG_ADD_GYRO_CONFIG_2   0x02
#define REG_ADD_XG_OFFS_USRH	0x03
#define REG_ADD_XG_OFFS_USRL	0x04
#define REG_ADD_YG_OFFS_USRH	0x05
#define REG_ADD_YG_OFFS_USRL	0x06
#define REG_ADD_ZG_OFFS_USRH	0x07
#define REG_ADD_ZG_OFFS_USRL	0x08
#define REG_ADD_XA_OFFS_H		0x14
#define REG_ADD_XA_OFFS_L		0x15
#define REG_ADD_YA_OFFS_H		0x17
#define REG_ADD_YA_OFFS_L		0x18
#define REG_ADD_ZA_OFFS_H		0x1A
#define REG_ADD_ZA_OFFS_L		0x1B
#define REG_VAL_BIT_GYRO_DLPCFG_2   0x10 /* bit[5:3] */
#define REG_VAL_BIT_GYRO_DLPCFG_4   0x20 /* bit[5:3] */
#define REG_VAL_BIT_GYRO_DLPCFG_6   0x30 /* bit[5:3] */
#define REG_VAL_BIT_GYRO_FS_250DPS  0x00 /* bit[2:1] */
#define REG_VAL_BIT_GYRO_FS_500DPS  0x02 /* bit[2:1] */
#define REG_VAL_BIT_GYRO_FS_1000DPS 0x04 /* bit[2:1] */
#define REG_VAL_BIT_GYRO_FS_2000DPS 0x06 /* bit[2:1] */
#define REG_VAL_BIT_GYRO_DLPF       0x01 /* bit[0]   */
#define REG_ADD_ACCEL_SMPLRT_DIV_1  0x10
#define REG_ADD_ACCEL_SMPLRT_DIV_2  0x11
#define REG_ADD_ACCEL_CONFIG        0x14
#define REG_ADD_ACCEL_CONFIG_2      0x15
#define REG_VAL_BIT_ACCEL_DLPCFG_2  0x10 /* bit[5:3] */
#define REG_VAL_BIT_ACCEL_DLPCFG_4  0x20 /* bit[5:3] */
#define REG_VAL_BIT_ACCEL_DLPCFG_6  0x30 /* bit[5:3] */
#define REG_VAL_BIT_ACCEL_FS_2g     0x00 /* bit[2:1] */
#define REG_VAL_BIT_ACCEL_FS_4g     0x02 /* bit[2:1] */
#define REG_VAL_BIT_ACCEL_FS_8g     0x04 /* bit[2:1] */
#define REG_VAL_BIT_ACCEL_FS_16g    0x06 /* bit[2:1] */
#define REG_VAL_BIT_ACCEL_DLPF      0x01 /* bit[0]   */
#define REG_ADD_TEMP_CONFIG			0x53

/* user bank 3 register */
#define REG_ADD_I2C_MST_CTRL	0x01
#define REG_VAL_I2C_MST_CTRL_CLK_400KHZ	0x07
#define REG_ADD_I2C_SLV0_ADDR   0x03
#define REG_ADD_I2C_SLV0_REG    0x04
#define REG_ADD_I2C_SLV0_CTRL   0x05
#define REG_VAL_BIT_SLV0_EN     0x80
#define REG_VAL_BIT_MASK_LEN    0x07
#define REG_ADD_I2C_SLV0_DO     0x06
#define REG_ADD_I2C_SLV1_ADDR   0x07
#define REG_ADD_I2C_SLV1_REG    0x08
#define REG_ADD_I2C_SLV1_CTRL   0x09
#define REG_ADD_I2C_SLV1_DO     0x0A

/* define ICM-20948 Register  end */

/* define ICM-20948 MAG Register  */
#define REG_ADD_MAG_WIA1    0x00
#define REG_VAL_MAG_WIA1    0x48
#define REG_ADD_MAG_WIA2    0x01
#define REG_VAL_MAG_WIA2    0x09
#define REG_ADD_MAG_ST1     0x10
#define REG_ADD_MAG_DATA    0x11
#define REG_ADD_MAG_CNTL2   0x31
#define REG_VAL_MAG_MODE_PD     0x00
#define REG_VAL_MAG_MODE_SM     0x01
#define REG_VAL_MAG_MODE_10HZ   0x02
#define REG_VAL_MAG_MODE_20HZ   0x04
#define REG_VAL_MAG_MODE_50HZ   0x05
#define REG_VAL_MAG_MODE_100HZ  0x08
#define REG_VAL_MAG_MODE_ST     0x10
#define REG_ADD_MAG_CNTL3   0x32
#define REG_VAL_MAG_RESET	0x01
/* define ICM-20948 MAG Register  end */


typedef enum ICM_BANK
{
    BANK_0 		   = 0x00,
    BANK_1 		   = 0x10,
    BANK_2 		   = 0x20,
    BANK_3 		   = 0x30,
    BANK_UNDEFINED = 0xFF,
}ICM_BANK;
typedef enum TEMP_DLPF_BANDWIDTH
{
    TEMP_DLPF_NONE			  = 0,
    TEMP_DLPF_BANDWIDTH_218HZ = 1,
    TEMP_DLPF_BANDWIDTH_124HZ = 2,
    TEMP_DLPF_BANDWIDTH_66HZ  = 3,
    TEMP_DLPF_BANDWIDTH_34HZ  = 4,
    TEMP_DLPF_BANDWIDTH_17HZ  = 5,
    TEMP_DLPF_BANDWIDTH_9HZ	  = 6
}TEMP_DLPF_BANDWIDTH;
typedef enum ACC_RANGE
{
    ACC_RANGE_2G  = 0,
    ACC_RANGE_4G  = 1,
    ACC_RANGE_8G  = 2,
    ACC_RANGE_16G = 3
}ACC_RANGE;
typedef enum ACC_DLPF_BANDWIDTH
{
    ACC_DLPF_NONE 			 = 0b00000000,
    ACC_DLPF_BANDWIDTH_246HZ = 0b00001001,
    ACC_DLPF_BANDWIDTH_111HZ = 0b00010001,
    ACC_DLPF_BANDWIDTH_50HZ	 = 0b00011001,
    ACC_DLPF_BANDWIDTH_24HZ	 = 0b00100001,
    ACC_DLPF_BANDWIDTH_12HZ	 = 0b00101001,
    ACC_DLPF_BANDWIDTH_6HZ	 = 0b00110001,
    ACC_DLPF_BANDWIDTH_473HZ = 0b00111001
}ACC_DLPF_BANDWIDTH;

 typedef enum GYRO_RANGE_DLPF_BANDWIDTH
    {
		GYRO_DLPF_NONE			  = 0b00000000,
		GYRO_DLPF_BANDWIDTH_197HZ = 0b00000001,
		GYRO_DLPF_BANDWIDTH_152HZ = 0b00001001,
		GYRO_DLPF_BANDWIDTH_120HZ = 0b00010001,
		GYRO_DLPF_BANDWIDTH_51HZ  = 0b00011001,
		GYRO_DLPF_BANDWIDTH_24HZ  = 0b00100001,
		GYRO_DLPF_BANDWIDTH_12HZ  = 0b00101001,
		GYRO_DLPF_BANDWIDTH_6HZ	  = 0b00110001,
		GYRO_DLPF_BANDWIDTH_361HZ = 0b00111001
    }GYRO_RANGE_DLPF_BANDWIDTH;
typedef enum GYRO_RANGE
{
    GYRO_RANGE_250DPS  = 0,
    GYRO_RANGE_500DPS  = 1,
    GYRO_RANGE_1000DPS = 2,
    GYRO_RANGE_2000DPS = 3
}GYRO_RANGE;

uint8_t ICM_getID(void);

void ICM_20948_Init(void);

int  Hal_ICM20948_calibration(int *pval);

int8_t Enter_sleep_mode(int8_t flag);

void Hal_ICM20948(unsigned int benableMag,
					unsigned int benableACC,
					int *pfw_angle,
					int *phori_angle,
					int *pvert_angle);


#endif